package com.utooo.service.purchase;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.utooo.dao.purchase.ContractAgreementsStageMapper;
import com.utooo.dao.purchase.ContractAttachmentMapper;
import com.utooo.dao.purchase.ContractObjectMapper;
import com.utooo.dao.purchase.ContractPartyAMapper;
import com.utooo.dao.purchase.ContractPartyBMapper;
import com.utooo.dao.purchase.PurchaseContractMapper;
import com.utooo.dao.purchase.ThirdPartyMapper;
import com.utooo.pojo.domain.purchase.contract.ContractAgreementsStageDO;
import com.utooo.pojo.domain.purchase.contract.ContractAttachmentDO;
import com.utooo.pojo.domain.purchase.contract.ContractObjectDO;
import com.utooo.pojo.domain.purchase.contract.ContractPartyADO;
import com.utooo.pojo.domain.purchase.contract.ContractPartyBDO;
import com.utooo.pojo.domain.purchase.contract.PurchaseContractDO;
import com.utooo.pojo.domain.purchase.contract.ThirdPartyDO;
import com.utooo.pojo.domain.purchase.task.PurchaseTaskManagementDO;
import com.utooo.pojo.dto.purchase.contract.ContractAgreementsStageDTO;
import com.utooo.pojo.dto.purchase.contract.ContractAttachmentDTO;
import com.utooo.pojo.dto.purchase.contract.ContractObjectDTO;
import com.utooo.pojo.dto.purchase.contract.ContractPartyADTO;
import com.utooo.pojo.dto.purchase.contract.ContractPartyBDTO;
import com.utooo.pojo.dto.purchase.contract.PurchaseContractDTO;
import com.utooo.pojo.dto.purchase.contract.ThirdPartyDTO;
import com.utooo.pojo.enums.PurchaseTaskStatus;
import com.utooo.pojo.vo.purchase.contract.PurchaseContractVO;
import com.utooo.service.supplier.SupplierContractService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PurchaseContractServiceImpl extends ServiceImpl<PurchaseContractMapper, PurchaseContractDO>
        implements PurchaseContractService {

    @Resource
    private ContractPartyAMapper contractPartyAMapper;
    @Resource
    private ContractPartyBMapper contractPartyBMapper;
    @Resource
    private ThirdPartyMapper thirdPartyMapper;
    @Resource
    private ContractObjectMapper contractObjectMapper;
    @Resource
    private ContractAgreementsStageMapper contractAgreementsStageMapper;
    @Resource
    private ContractAttachmentMapper contractAttachmentMapper;
    @Resource
    private PurchaseTaskManagementService purchaseTaskManagementService;
    @Resource
    private PurchaseContractMapper purchaseContractMapper;
    @Resource
    private SupplierContractService supplierContractService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addContract(PurchaseContractDTO purchaseContractDTO)  {
        String title = purchaseContractDTO.getTitle();
        if (StrUtil.isBlank(title)) {
            log.error("合同标题为空！");
            return false;
        }
        List<ContractObjectDTO> objects = purchaseContractDTO.getMaterialDetailList();
        Map<String, Integer> materialDemandQuantityMap =
                objects
                        .stream()
                        .filter(i -> i.getDemandQuantity() != null)
                        .collect(Collectors.toMap(ContractObjectDTO::getTaskId,
                                ContractObjectDTO::getDemandQuantity, (k1, k2) -> k1));
        List<PurchaseTaskManagementDO> tasks =
                purchaseTaskManagementService.listByIds(materialDemandQuantityMap.keySet());
        Map<String, PurchaseTaskManagementDO> taskMap = new HashMap<>();
        if (CollUtil.isNotEmpty(tasks)) {
            taskMap = tasks.stream()
                    .collect(Collectors.toMap(PurchaseTaskManagementDO::getId, Function.identity(), (k1, k2) -> k1));
            for (Map.Entry<String, Integer> entry : materialDemandQuantityMap.entrySet()) {
                String k = entry.getKey();
                Integer v = entry.getValue();
                PurchaseTaskManagementDO task = taskMap.get(k);
                if (task != null) {
                    Integer pendingAcceptanceQuantity = task.getPendingAcceptanceQuantity();
                    if (pendingAcceptanceQuantity != null && v > pendingAcceptanceQuantity) {
                        throw new IllegalArgumentException("The demand quantity cannot be greater than the pending accept quantity");
                    }
                }
            }
        }


        PurchaseContractDO contractDO = new PurchaseContractDO();
        BeanUtil.copyProperties(purchaseContractDTO, contractDO);
        // 生成合同编号
        contractDO.setContractNo(supplierContractService.generateContractNo());
        this.save(contractDO);
        String contractId = contractDO.getId();
        // 合同甲方
        List<ContractPartyADTO> partyAList = purchaseContractDTO.getPartyAList();
        if (CollUtil.isNotEmpty(partyAList)) {
            List<ContractPartyADO> contractPartyAs = BeanUtil.copyToList(partyAList, ContractPartyADO.class);
            contractPartyAs.forEach(i ->{
                i.setForeignId(contractId);
                contractPartyAMapper.insert(i);
            });
        }
        // 合同乙方
        List<ContractPartyBDTO> partyBList = purchaseContractDTO.getPartyBList();
        if (CollUtil.isNotEmpty(partyBList)) {
            List<ContractPartyBDO> contractPartyBs = BeanUtil.copyToList(partyBList, ContractPartyBDO.class);
            contractPartyBs.forEach(i ->{
                i.setForeignId(contractId);
                contractPartyBMapper.insert(i);
            });
        }
        // 合同签署第三方
        List<ThirdPartyDTO> thirdPartyList = purchaseContractDTO.getThirdPartyList();
        if (CollUtil.isNotEmpty(thirdPartyList)) {
            List<ThirdPartyDO> thirdParties = BeanUtil.copyToList(partyBList, ThirdPartyDO.class);
            thirdParties.forEach(i ->{
                i.setForeignId(contractId);
                thirdPartyMapper.insert(i);
            });
        }
        // 合同标的
        List<ContractObjectDTO> materialDetailList = purchaseContractDTO.getMaterialDetailList();
        if (CollUtil.isNotEmpty(materialDetailList)) {
            List<ContractObjectDO> contractObjects = BeanUtil.copyToList(materialDetailList, ContractObjectDO.class);
            contractObjects.forEach(i ->{
                i.setForeignId(contractId);
                contractObjectMapper.insert(i);
            });

        }
        // 合同约定阶段
        List<ContractAgreementsStageDTO> contractStageList = purchaseContractDTO.getStageList();
        if (CollUtil.isNotEmpty(contractStageList)) {
            List<ContractAgreementsStageDO> stages = BeanUtil.copyToList(contractStageList, ContractAgreementsStageDO.class);
            stages.forEach(i ->{
                i.setForeignId(contractId);
                contractAgreementsStageMapper.insert(i);
            });
        }
        // 合同附件
        List<ContractAttachmentDTO> attachmentList = purchaseContractDTO.getContractInfoList();
        if (CollUtil.isNotEmpty(attachmentList)) {
            List<ContractAttachmentDO> contractAttachments = BeanUtil.copyToList(attachmentList, ContractAttachmentDO.class);
            contractAttachments.forEach(i ->{
                i.setForeignId(contractId);
                contractAttachmentMapper.insert(i);
            });
        }

        if (CollUtil.isNotEmpty(tasks)) {
            Map<String, PurchaseTaskManagementDO> finalTaskMap = taskMap;
            materialDemandQuantityMap.forEach((k, v) -> {
                PurchaseTaskManagementDO task = finalTaskMap.get(k);
                if (task != null) {
                    Integer pendingAcceptanceQuantity = task.getPendingAcceptanceQuantity();
                    if (pendingAcceptanceQuantity != null) {
                        Integer acceptedQuantity = task.getAcceptedQuantity();
                        if (acceptedQuantity == null) {
                            acceptedQuantity = 0;
                        }

                        if (v < pendingAcceptanceQuantity) {
                            task.setStatus(PurchaseTaskStatus.PARTIALLY_ACCEPTED.getCode());
                            task.setPendingAcceptanceQuantity(pendingAcceptanceQuantity - v);
                            task.setAcceptedQuantity(acceptedQuantity + v);
                        } else {
                            task.setStatus(PurchaseTaskStatus.ACCEPTED.getCode());
                            task.setPendingAcceptanceQuantity(0);
                            task.setAcceptedQuantity(acceptedQuantity + v);
                        }
                        purchaseTaskManagementService.updateById(task);
                    }
                }
            });
        }
        return true;
    }

    @Override
    public List<PurchaseContractVO> getRelatedContracts(String supplierId, String companyId) {
        return purchaseContractMapper.getRelatedContracts(supplierId, companyId);
    }
}